<?php
/**
* DPMatchReserve copyright (c) 2008 sk89q
* @ http://digitalpaint.therisenrealm.com
* 
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* 
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*/

require_once "./functions.php";
require_once "include/DigitalPaintServer.php";

$smarty->assign('title', 'Lease a Match Server');

$errors = array();

// ===============================
// Get input
// ===============================

$server = $_POST['server'];
$password = $_POST['password'];
$login_password = $_POST['login'];
$bot_check = trim($_POST['botcheck']);

$server_info = @$CONFIG['servers'][$server];

if(!isset($CONFIG['servers'][$server]) && ($CONFIG['enable_autoselect'] && $server != "autoselect"))
    $errors[] = 'A valid server was not selected. Select a valid server to lease.';

if(strval($password) === "")
    $errors[] = 'A password must be provided for players to use to login.';
else if(preg_match("#[^A-Za-z0-9\\-_!@\\#\\$%\\^&\\*\\(\\)\\+=\\\\/\\{\\}\\[\\]\\.,\\?><~`\\|:]#", $password))
    $errors[] = 'The password provided contained invalid characters. Stick to standard ASCII characters. No spaces are allowed.';
else if(strlen($password) > 30)
    $errors[] = 'The password is too long. Shorten it.';

if(strval($login_password) === "")
    $errors[] = 'A login password must be provided for you to use to change the map and manage players.';
else if(preg_match("#[^A-Za-z0-9\\-_!@\\#\\$%\\^&\\*\\(\\)\\+=\\\\/\\{\\}\\[\\]\\.,\\?><~`\\|:]#", $login_password))
    $errors[] = 'The login password provided contained invalid characters. Stick to standard ASCII characters. No spaces are allowed.';
else if(strlen($login_password) > 30)
    $errors[] = 'The login password is too long. Shorten it.';

if($CONFIG['bot_check_string'] && $bot_check != $CONFIG['bot_check_string'])
    $errors[] = 'Enter the correct value for the spam-bot check';

// ===============================
// Process custom settings
// ===============================

$custom_vars = array();

foreach($CONFIG['user_settings'] as $cvar => $opt)
{
    $input = $_POST["var_$cvar"];
    if(strval($input) === "") continue;
    
    if($opt['type'] == 'int')
    {
        if(!is_numeric($input))
        {
            $errors[] = "The value of <em>$cvar</em> must be an integer";
        }
        else if($input < $opt['min'])
        {
            $errors[] = "The value of <em>$cvar</em> must be equal to or greater than {$opt['min']}";
        }
        else if($input > $opt['max'])
        {
            $errors[] = "The value of <em>$cvar</em> must be equal to or less than {$opt['max']}";
        }
        else
        {
            $custom_vars[$cvar] = intval($input);
        }
    }
    else if($opt['type'] == 'float')
    {
        if(!is_numeric($input))
        {
            $errors[] = "The value of <em>$cvar</em> must be a float";
        }
        else if($input < $opt['min'])
        {
            $errors[] = "The value of <em>$cvar</em> must be equal to or greater than {$opt['min']}";
        }
        else if($input > $opt['max'])
        {
            $errors[] = "The value of <em>$cvar</em> must be equal to or less than {$opt['max']}";
        }
        else
        {
            $custom_vars[$cvar] = floatval($input);
        }
    }
    else if($opt['type'] == 'bool')
    {
        if($input == "true")
        {
            $custom_vars[$cvar] = '1';
        }
        else if($input == "false")
        {
            $custom_vars[$cvar] = '0';
        }
    }
    /*else if($opt['type'] == 'string')
    {
        if(strlen($input) > 200)
        {
            $errors[] = "The value of <em>$cvar</em> is too long";
        }
        else
        {
            $custom_vars[$cvar] = $input;
        }
    }*/
}

// ===============================
// Is the server available?
// Or auto-select as necessary
// ===============================

if(count($errors) == 0)
{
    try
    {
        if($CONFIG['enable_autoselect'] && $server == "autoselect")
        {
            $found_open = false;
            
            foreach($CONFIG['servers'] as $server => $server_info)
            {
                $paintball = new DigitalPaintServer($server_info['host'], $server_info['port'], $server_info['rcon_password']);

                if(!$paintball->is_online())
                {
                    continue;
                }
                else if(count($paintball->get_players()) > 0)
                {
                    continue;
                }
                else if($CONFIG['grace_period'] > 0)
                {
                    $last_lease = @filemtime("cache/last_lease_$server");
                    
                    if($last_lease > time()-$CONFIG['grace_period'])
                    {
                        continue;
                    }
                }
                
                $found_open = true;
                break;
            }
            
            if(!$found_open)
            {
                $errors[] = "All servers are currently unavailable; please try again later";
            }
        }
        else
        {
            $paintball = new DigitalPaintServer($server_info['host'], $server_info['port'], $server_info['rcon_password']);

            if(!$paintball->is_online())
            {
                $errors[] = "<em>".htmlspecialchars($server_info['name'])."</em> is currently offline; please try another server";
            }
            else if(count($paintball->get_players()) > 0)
            {
                $errors[] = "<em>".htmlspecialchars($server_info['name'])."</em> is currently in use; please try another server";
            }
            else if($CONFIG['grace_period'] > 0)
            {
                $last_lease = @filemtime("cache/last_lease_$server");
                
                if($last_lease > time()-$CONFIG['grace_period'])
                {
                    $errors[] = "<em>".htmlspecialchars($server_info['name'])."</em> was leased by another individual too recently (and it is in the grace period); try another server";
                }
            }
        }
    }
    catch(DPSBadRCONPasswordException $e)
    {
        show_fatal_error("Please report this error to the webmaster of this website: the configured RCON password for <em>".htmlspecialchars($server_info['name'])."</em> is incorrect");
    }
    catch(DPSRCONPasswordUnsetException $e)
    {
        show_fatal_error("Please report this error to the webmaster of this website: there is no configured RCON password for <em>".htmlspecialchars($server_info['name'])."</em>");
    }
    catch(DPSConnectionException $e)
    {
        show_fatal_error("The connection to <em>".htmlspecialchars($server_info['name'])."</em> was lost; please try again");
    }
}

// ===============================
// Any errors?
// ===============================

if(count($errors) > 0)
{
    $smarty->assign('errors', $errors);
    $smarty->display('error.tpl');
    exit;
}

// ===============================
// Lease it out
// ===============================

// Grace period
if($CONFIG['grace_period'] > 0)
{
    if(!$fp = @fopen("cache/last_lease_$server", "w"))
    {
        show_fatal_error("Please report this error to the webmaster of this website: could not write lease grace tracking files to the cache directory (chmod may be necessary)");
    }
    fclose($fp);
}

try
{    
    // What variables do we need to change?
    $login_vars = array('password' => $password,
                        "oppass{$server_info['op_pass_num']}" => $login_password);

    $changed_vars = array_merge($CONFIG['default_settings'], $custom_vars, $login_vars);

    foreach($changed_vars as $cvar => $value)
    {
        $paintball->rcon_set_variable($cvar, $value);
    }

    // Load the default map
    if(isset($CONFIG['default_map']) && !empty($CONFIG['default_map']))
    {
        $paintball->rcon_new_map($CONFIG['default_map']);
    }
}
catch(DPSBadRCONPasswordException $e)
{
    show_fatal_error("Please report this error to the webmaster of this website: the configured RCON password for <em>".htmlspecialchars($server_info['name'])."</em> is incorrect");
}
catch(DPSRCONPasswordUnsetException $e)
{
    show_fatal_error("Please report this error to the webmaster of this website: there is no configured RCON password for <em>".htmlspecialchars($server_info['name'])."</em>");
}
catch(DPSConnectionException $e)
{
    show_fatal_error("The connection to <em>".htmlspecialchars($server_info['name'])."</em> was lost; please try again");
}

// ===============================
// Send it off
// ===============================

header(sprintf("Location: {$CONFIG['base_url']}/play.php?server=%d&password=%s&login=%s", $server, urlencode($password), urlencode($login_password)));
exit;
?>